<template>
    <u-popup
        :maskCloseAble="maskCloseAble"
        mode="bottom"
        :popup="false"
        v-model="value"
        length="auto"
        :safeAreaInsetBottom="safeAreaInsetBottom"
        border-radius="34"
        @close="onClose"
        :z-index="zIndex"
    >
        <view class="e-region-picker">
            <view class="e-picker-header">
                <view class="e-picker__title">{{ title }}</view>
                <view class="e-picker__tab u-flex u-border-bottom">
                    <view
                        class="item"
                        @click="onTab(0)"
                        :class="{ active: current === 0 }"
                        >{{ activeTitle[0] }}<text class="line"></text
                    ></view>
                    <view
                        class="item"
                        @click="onTab(1)"
                        :class="{ active: current === 1 }"
                        >{{ activeTitle[1] }}<text class="line"></text
                    ></view>
                    <view
                        class="item"
                        @click="onTab(2)"
                        :class="{ active: current === 2 }"
                        >{{ activeTitle[2] }}<text class="line"></text
                    ></view>
                </view>
            </view>
            <view class="e-picker-body">
                <scroll-view
                    scroll-y="true"
                    :scroll-top="scrollTop"
                    @scroll="onScroll"
                    class="e-picker-scroll-view"
                >
                    <block v-if="!reset && current === 0">
                        <view
                            class="e-picker-item"
                            v-for="(item, index) in provinces"
                            :key="index"
                            :class="item.code == selectData[0] ? 'active' : ''"
                            @click="onProvince(item)"
                            >{{ item.name }}</view
                        >
                    </block>
                    <block v-else-if="!reset && current === 1">
                        <view
                            class="e-picker-item"
                            v-for="(item, index) in citys"
                            :key="index"
                            :class="item.code == selectData[1] ? 'active' : ''"
                            @click="onCity(item)"
                            >{{ item.name }}</view
                        >
                    </block>
                    <block v-else-if="!reset && current === 2">
                        <view
                            class="e-picker-item"
                            v-for="(item, index) in areas"
                            :key="index"
                            :class="item.code == selectData[2] ? 'active' : ''"
                            @click="onAreas(item)"
                            >{{ item.name }}</view
                        >
                    </block>
                </scroll-view>
            </view>
        </view>
    </u-popup>
</template>

<script>
import addressData from "@/utils/Area.json";
export default {
    name: "addressSelector",
    data() {
        return {
            // 当前级别
            current: 0,
            activeTitle: ["请选择", "", ""], // 标题显示
            selectData: [], // 选中的下标
            provinces: [],
            citys: [],
            areas: [],
            province: 0,
            city: 0,
            area: 0,
            menuHeight: 0, // 左边菜单的高度
            menuItemHeight: 0, // 左边菜单item的高度
            reset: false,
            scrollTop: 0,
            old: {
                scrollTop: 0,
            },
        };
    },
    props: {
        // 默认显示地区的编码，可传类似["13", "1303", "130304"]
        areaCode: {
            type: Array,
            default() {
                return [];
            },
        },
        safeAreaInsetBottom: {
            type: Boolean,
            default: false,
        },
        // 是否允许通过点击遮罩关闭Picker
        maskCloseAble: {
            type: Boolean,
            default: true,
        },
        // 通过双向绑定控制组件的弹出与收起
        value: {
            type: Boolean,
            default: false,
        },
        // 弹出的z-index值
        zIndex: {
            type: [String, Number],
            default: 10075,
        },
        // 顶部标题
        title: {
            type: String,
            default: "",
        },
    },
    mounted() {
        this.init();
    },
    watch: {
        areaCode() {
            this.reset = true;
            setTimeout(() => this.init(), 10);
        },
        value(n) {
            if (n) {
                this.reset = true;
                setTimeout(() => this.init(), 10);
            }
        },
    },
    methods: {
        async init() {
            this.tabIndex = 0;
            this.reset = false;
            await this.setProvinces();
            await this.setCitys();
            await this.setAreas();
        },
        async setProvinces() {
            let tmp = "";
            if (this.areaCode.length) {
                tmp = this.areaCode[0];
                this.selectData = this.areaCode;
            }
            // 历遍省份数组匹配
            addressData.map((v) => {
                if (v.code == tmp) {
                    this.activeTitle[0] = v.name;
                    this.citys = v.children;
                }
            });
            this.provinces = addressData;
        },
        setCitys() {
            let tmp = "";
            if (this.areaCode.length) {
                tmp = this.areaCode[1];
            }
            this.citys.map((v) => {
                if (v.code == tmp) {
                    this.activeTitle[1] = v.name;
                    this.areas = v.children;
                }
            });
        },
        setAreas() {
            let tmp = "";
            if (this.areaCode.length) {
                tmp = this.areaCode[2];
            }
            this.areas.map((v) => {
                if (v.code == tmp) {
                    this.activeTitle[2] = v.name;
                }
            });
        },
        // 点击标题事件
        async onTab(index) {
            if (index == this.current) return;
            this.current = index;
            // 如果为0，意味着尚未初始化
            if (this.menuHeight == 0 || this.menuItemHeight == 0) {
                await this.getElRect("e-picker-scroll-view", "menuHeight");
                await this.getElRect("e-picker-item", "menuItemHeight");
            }
            let num = 0;
            if (index == 0) {
                num = this.provinces.findIndex(
                    (item) => item.code == this.selectData[index]
                );
            } else if (index == 1) {
                num = this.citys.findIndex(
                    (item) => item.code == this.selectData[index]
                );
            } else if (index == 3) {
                num = this.areas.findIndex(
                    (item) => item.code == this.selectData[index]
                );
            }
            setTimeout(() => {
                if (num != -1) {
                    this.scrollTop =
                        num * this.menuItemHeight +
                        this.menuItemHeight / 2 -
                        this.menuHeight / 2;
                } else {
                    this.scrollTop = 0;
                }
            }, 50);
        },
        onProvince(item) {
            this.current = 1;
            this.citys = item.children;
            this.selectData = [item.code];
            this.activeTitle = [item.name, "请选择", ""];
            this.scrollTop = this.old.scrollTop;
            setTimeout(() => {
                this.scrollTop = 0;
            }, 50);
        },
        onCity(item) {
            this.current = 2;
            this.areas = item.children;
            this.selectData = [this.selectData[0], item.code];
            this.activeTitle = [this.activeTitle[0], item.name, "请选择"];
            this.scrollTop = this.old.scrollTop;
            setTimeout(() => {
                this.scrollTop = 0;
            }, 50);
        },
        onAreas(item) {
            this.selectData[2] = item.code;
            this.activeTitle[2] = item.name;
            this.onConfirm();
        },
        onConfirm() {
            this.onClose();
            this.$emit("confirm", this.activeTitle, this.selectData);
        },
        onClose() {
            this.$emit("input", false);
        },
        onScroll(e) {
            this.old.scrollTop = e.detail.scrollTop;
        },
        // 获取一个目标元素的高度
        getElRect(elClass, dataVal) {
            new Promise((resolve, reject) => {
                const query = uni.createSelectorQuery().in(this);
                query
                    .select("." + elClass)
                    .fields(
                        {
                            size: true,
                        },
                        (res) => {
                            // 如果节点尚未生成，res值为null，循环调用执行
                            if (!res) {
                                setTimeout(() => {
                                    this.getElRect(elClass);
                                }, 10);
                                return;
                            }
                            this[dataVal] = res.height;
                        }
                    )
                    .exec();
            });
        },
    },
};
</script>

<style lang="scss" scope>
.e-region-picker {
    position: relative;
    z-index: 999;
    padding: 0 30rpx;
}
.e-picker-header {
    .e-picker__title {
        padding: 26rpx 0;
        font-size: 32rpx;
        font-weight: 400;
        color: $edu-main-color;
        text-align: center;
    }
    .e-picker__tab {
        .item {
            margin-right: 56rpx;
            padding: 20rpx 0;
            position: relative;
            font-size: 28rpx;
            font-weight: 400;
            color: $edu-main-color;
            .line {
                position: absolute;
                bottom: 0;
                left: 0;
                right: 0;
                height: 4rpx;
                border-radius: 2rpx;
                @include bg-color();
                opacity: 0;
            }
            &.active .line {
                opacity: 1;
            }
        }
    }
}

.e-picker-body {
    height: 800rpx;
    margin-top: 20rpx;
    .e-picker-scroll-view {
        height: 100%;
    }
    .e-picker-item {
        font-size: 28rpx;
        font-weight: 400;
        color: $edu-main-color;
        padding: 20rpx 0;
        &.active {
            @include text-color();
        }
    }
    .e-picker-item + .e-picker-item {
        // margin-top: 40rpx;
    }
}
</style>
